package com.starsoft.quant.web;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.starsoft.frame.core.web.WebUtil;
import com.starsoft.frame.util.DateUtil;
import com.starsoft.frame.util.StringUtil;
import com.starsoft.quant.bean.QuantAcount;
import com.starsoft.quant.service.AnalysisService;
import com.starsoft.quant.service.QuantAcountService;
import com.starsoft.smdc.bean.SmdcSecurity;
import com.starsoft.smdc.service.HolidayService;
import com.starsoft.smdc.service.SecurityService;
import com.starsoft.smdc.util.SecurityType;
import com.starsoft.trade.service.TradeAcountService;

@RestController
@RequestMapping("/quant/analysis")
public class AnalysisController {
	
	@Autowired
	SecurityService securityService;
	
	@Autowired
	AnalysisService analysisService;
	
	@Autowired
	HolidayService holidayService;
	
	@Autowired
	TradeAcountService tradeAcountService;
	
	@Autowired
	QuantAcountService quantAcountService;
	
	@RequestMapping("/modelsec")
	public Map<String, Object> getModelSec(HttpServletRequest request) {
		QuantAcount quantAccount = quantAcountService.getAcount(Integer.parseInt(request.getParameter("acountId")));
		String secList =  quantAcountService.getSecList(quantAccount.getAcountId());
		List<String> secIds = Arrays.asList(secList.split(","));
		List<String> secIdsNew = new ArrayList<>();
		secIds.forEach(secId->secIdsNew.add(secId.trim()));
		List<SmdcSecurity> securityList = securityService.get(secIdsNew);
		
		Map<String, Object> model = new HashMap<>();
		model.put("secList", securityList);
		SmdcSecurity baseSec = tradeAcountService.getBaseIndex(quantAccount.getAcountId());
		model.put("baseList", Arrays.asList(baseSec));
		return model;
	}
	
	@RequestMapping("/query")
	public Map<String, Object> get(HttpServletRequest request) {
		Map<String, Object> model = new HashMap<>();
		List<Date> dateRange = this.getDateRange(request);
		Date beginDate = dateRange.get(0);
		Date endDate = dateRange.get(1);
		List<String> secIds = WebUtil.getList(request, "secIds");
		List<String> secBaseIds = WebUtil.getList(request, "secBaseIds");

		List<SmdcSecurity> secs = securityService.get(secIds);
		List<SmdcSecurity> secsBase = securityService.get(secBaseIds);

		List<Date> timeLine = holidayService.getBusinessDayList(beginDate, endDate, 250);
		List<String> timeLineStr = timeLine.stream().map(t -> DateUtil.toString(t)).collect(Collectors.toList());
		
		List<Map<String, Object>> regression = new ArrayList<>();
		for (SmdcSecurity sec : secs) {
			for (SmdcSecurity secBase : secsBase) {
				Map<String, Object> oneResult = analysisService.getRegression(sec, secBase, timeLine);
				regression.add(oneResult);
			}
		}

		List<Map<String, Object>> risk = new ArrayList<>();
		for (SmdcSecurity sec : secs) {
			Map<String, Object> oneResult = analysisService.getRisk(sec, beginDate, endDate);
			risk.add(oneResult);
		}

		secs.addAll(secsBase);
		Map<String, List<Double>> dataLine = new LinkedHashMap<>();
		for (SmdcSecurity sec : secs) {
			SecurityType secType = SecurityType.get(sec);
			if (secType != SecurityType.fund || "CLOSE".equals(sec.getFundTradetype())) {
				List<Double> oneResult = analysisService.getProfitLine(sec, timeLine);
				dataLine.put(sec.getSecName(), oneResult);
			}
			if(secType == SecurityType.bond || secType == SecurityType.fund){
				List<Double> oneResult = analysisService.getProfitLineNav(sec, timeLine);
				dataLine.put(sec.getSecName() + "_静", oneResult);
			}
			if (SecurityType.index == secType) {
				List<Double> oneResult = analysisService.getProfitFullEarning(sec, timeLine);
				if (oneResult != null) dataLine.put(sec.getSecName() + "_全", oneResult);
			}
		}

		model.put("beginDate", beginDate);
		model.put("endDate", endDate);
		model.put("risk", risk);
		model.put("regression", regression);
		model.put("dataLine", dataLine);
		model.put("timeLine", timeLineStr);
		return model;
	}
	
	private List<Date> getDateRange(HttpServletRequest request){
		if(StringUtil.isTrue(request.getParameter("analysisDateType"))){
			Date endDate = holidayService.getNextBusinessDay(new Date(), -1);
			String dateType = request.getParameter("dateType");
			if(StringUtil.isEmpty(dateType)){
				dateType = "1";
			}
			Date beginDate = DateUtil.bumpDate(endDate, 0, -Integer.parseInt(dateType), 0);
			beginDate = holidayService.getNextBusinessDay(beginDate, -1);
			return Arrays.asList(beginDate, endDate);
		} else {
			Date beginDate = WebUtil.getDate(request, "beginDate", "yyyy-MM-dd");
			Date endDate = WebUtil.getDate(request, "endDate", "yyyy-MM-dd");
			if(endDate == null){
				endDate = holidayService.getNextBusinessDay(new Date(), -1);
			}
			if(beginDate == null){
				beginDate = DateUtil.bumpDate(endDate, 0, -1, 0);
			}
			beginDate = holidayService.getNextBusinessDay(beginDate, -1);
			return Arrays.asList(beginDate, endDate);
		}
	}
}
